package com.mall.common.service.impl;

import static com.mall.common.Constants.OPERATE_TYPE_AUTHORITY;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.mall.common.dao.OperateDao;
import com.mall.common.domain.manage.Menu;
import com.mall.common.domain.manage.Operate;
import com.mall.common.hibernate.Finder;
import com.mall.common.service.OperateService;
import com.mall.common.service.RoleService;

/**
 * Service实现类 - 资源
 */
@Service
@Transactional(readOnly=true)
public class OperateServiceImpl extends BaseServiceImpl<Operate, Long> implements OperateService {
	@Resource private RoleService roleService;
	
	@Resource
	public void setBaseDao(OperateDao operateDao) {
		super.setBaseDao(operateDao);
	} 
	
	@Override
	@Transactional(readOnly=true)
	@Cacheable(value="authorization", key="'operate'+#menuId+','+#operate_type")
	public List<Operate> getOperatesWidthCondition(Long menuId, int operate_type){
		String hql = "from Operate operate where 1=1";
		Finder find = Finder.create(hql);
		if(operate_type != -1){
			find.append(" and operate.type=:type");
			find.setParam("type", operate_type);
		}
		
		if(menuId != null){
			find.append(" and operate.menu.id=:menu_id");
			find.setParam("menu_id", menuId);
			find.append(" order by operate.priority asc, operate.createDate asc");
		}
		
		return find.findHQLList();
	}
	
	@Transactional(readOnly=true)
	@Cacheable(value="authorization", key="'urlRole'")
	public Map<String, String> getAllUrlRole(){
		List<Operate> operates = getOperatesWidthCondition(null, -1);
		Map<String, String> urls = new HashMap<String, String>();
		
		if(operates != null && operates.size() > 0){
			for (Iterator<Operate> iterator = operates.iterator(); iterator.hasNext();) {
				Operate operate = iterator.next();
				if (operate.getType() == OPERATE_TYPE_AUTHORITY){
					urls.put(operate.getPattern(), operate.getRoleSetString());
				} else {
					urls.put(operate.getPattern(), operate.getMenu().getRoleSetString());
				}
			}
		}
		return urls;
	}
	
	// 重写方法，删除时刷新SpringSecurity权限信息
	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void remove(Operate operate) {
		super.remove(operate);
	}

	// 重写方法，删除时刷新SpringSecurity权限信息
	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void delete(Long id) {
		Operate operate = this.find(id);
		this.remove(operate);
	}

	// 重写方法，删除时刷新SpringSecurity权限信息
	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void delete(Long[] ids) {
		for (Long id : ids) {
			Operate operate = this.find(id);
			this.remove(operate);
		}
	}

	// 重写方法，保存时刷新SpringSecurity权限信息
	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void persist(Operate operate) {
		super.persist(operate);
	}

	// 重写方法，更新时刷新SpringSecurity权限信息
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public Operate updateByUpdater(Operate operate) {
		Assert.notNull(operate, "operate is null");
		super.updateByUpdater(operate);
		return operate;
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<Operate> getPrivOperates(List<Long> roleIds, Menu menu, boolean isDiaplayInToolBar){
		Assert.notNull(menu, "菜单不能为空");
		Finder finder = Finder.create("select distinct bean from Operate bean");
		if(roleIds != null && roleIds.size() > 0){
			finder.append(" join bean.roleSet r");
		}
		finder.append(" where bean.menu.id=:menu_id and bean.isDiaplayInToolBar=:isDiaplayInToolBar");
		finder.setParam("menu_id", menu.getId()).setParam("isDiaplayInToolBar", isDiaplayInToolBar);
		
		if(roleIds != null && roleIds.size() > 0){
			finder.append(" and r.id in (:roleIds)");
			finder.setParamList("roleIds", roleIds.toArray());
		}
		finder.append(" order by bean.priority asc");
		return finder.findHQLList();
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void updatePriority(Long[] ids, Integer[] priority){
		for (int i = 0, len = ids.length; i < len; i++) {
			Operate operate = this.find(ids[i]);
			operate.setPriority(priority[i]);
		}
	}

	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public Operate update(Operate entity) {
		return super.update(entity);
	}

}